﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public sealed class Clapper : MonoBehaviour
{
    const int FREQ = 44100;
    const int TIME = 1;
    const float AMPLITUDE = 25;
    public float clapThreshold = 0.4f;
    public float clapInterval = 0.5f;
    public float clapResetDelay = 1.0f;
    public bool debugPrints = false;
    public string[] methodCalls;
    public string[] arguments;
    AudioClip clip;
    List<float> clapTimes = new List<float>();
    Color backgroundColor = Color.black;

    void Start()
    {
        clip = Microphone.Start(null, true, TIME, FREQ);
    }

    void Update()
    {
        // If too much time has passed, reset clap counter and call appropriate method
        if (clapTimes.Count > 0 && Time.time - clapTimes[clapTimes.Count - 1] >= clapResetDelay)
        {
            if (debugPrints)
                print("Reset: " + clapTimes.Count + " claps");

            if (clapTimes.Count >= 2 && methodCalls.Length + 1 >= clapTimes.Count)
                SendMessage(methodCalls[clapTimes.Count - 2], arguments[clapTimes.Count - 2]);

            clapTimes.Clear();
        }

        // Get sample floats array
        float[] samples = new float[clip.samples];
        clip.GetData(samples, 0);

        // Check for claps
        for (int i = 0; i < samples.Length; i++)
        {
            // If the current sample is loud enough, and enough time has passed between the last loud enough sample,
            // we have a new clap.
            if (samples[i] > clapThreshold
                && (clapTimes.Count == 0 || Time.time - clapTimes[clapTimes.Count - 1] >= clapInterval))
            {
                Microphone.End(null);

                clapTimes.Add(Time.time);
                backgroundColor += Color.red * Random.Range(0.0f, 1.0f) + 
                    Color.green * Random.Range(0.0f, 1.0f) + 
                    Color.blue * Random.Range(0.0f, 1.0f);

                if (debugPrints)
                {
                    if (clapTimes.Count == 1)
                        print("Clap at " + Time.time + ".");
                    else
                        print("Clap at " + Time.time + ". Previous clap at " + clapTimes[clapTimes.Count - 2]);
                }

                clip = Microphone.Start(null, true, TIME, FREQ);
            }
        }

        backgroundColor *= 0.97f;
        Camera.main.backgroundColor = backgroundColor;
    }
}
